
/// MLSDEFORMER source code
/// by Alvaro Cuno, LCG-COPPE-UFRJ 
/// bugs? email-me: alvaroecp@gmail.com
/// January, 2007

#ifndef __DEFORMATION_MESH_H__
#define __DEFORMATION_MESH_H__

#include "../typedefs.h"
#include "../enumtypes.h"
#include "../core/constraints.h"
#include "../core/deformation.h"
#include "mesh.h"
#include "RBFfunction.h"
#include "weightsScheme.h"

#include <cpplapack.h>

//namespace MLS {

///
///
///
class DeformationMesh : public Deformation {
   
   typedef CPPL::dgematrix    MatrixCPPL;   ///< A CPPLapack matrix
   typedef CPPL::dcovector    VectorCPPL;   ///< A CPPLapack column vector
   
public:
   /// Constructors
   DeformationMesh();
   DeformationMesh(Mesh *model);
   virtual ~DeformationMesh();
   
   /// Sets the mesh to be deformed
   virtual void setMesh(Mesh *m);
   
   /// Prepares the deformer to compute the deformation
   virtual void setting(const Constraints *constraints);
   
   /// Executes the MLS-deformation induced by the deformed constraints
   ///@param constraints pointer to current constraints positions
   virtual void execute_deformation(const Constraints *constraints);
   
   /// Sets the technique for computing the rotation component
   void setRotationCompTech(RotationCompTech r) { rotation_mask = r; }
   
   /// Sets the technique for computing the translation component
   void setTranslationCompTech(TranslationCompTech t) { translation_mask = t; }
   
protected:
   /// Computes the rotation and translation components using an axis-angle representation
   void compRotTra_axisangle(unsigned int i);
   
   /// Computes the rotation and translation components using unit quaternions
   void compRotTra_unitquat(unsigned int i);
   
   /// Computes the rotation and translation components using unit dual quaternions
   void compRotTra_unitdualquat(unsigned int i);
   
   /// Computes the rotation using a simple average
   void compRotTra_simple(unsigned int i);
   
   /// Builds the matrix Q (see Eggert's paper)
   inline void buildQ(const Number v[]);
   /// Builds the matrix W (see Eggert's paper)
   inline void buildW(const Number v[]);
   /// Builds the matrix K (see Eggert's paper)
   inline void buildK(const Number v[]);
   
private:
   Mesh                  *model;
   
protected:
   
   vector<Point3>         ipositions; // initial vertex positions
   vector<Vector3>        inormals; // initial vertex normal
   
   
   RBFfunction           *rbf;
   
   MatrixCPPL             R; // a 3x3 rotation matrix
   MatrixCPPL             A, mW, mQ, C1, C3; // 4x4 temporal matrices used for computing R
   MatrixCPPL             mK, mI; // 3x3 temporal matrices used for computing R
   VectorCPPL             T; // a column translation vector
   
   unsigned int           rotation_mask; // method for computing the rotation component
   unsigned int           translation_mask; // method for computing the translation component
};

//} // end MLS namespace

#endif
